package com.itany.corejava.util;

/**
 * @author MissChen
 * @version 1.0
 * @date 2023 年11月27日 14:55
 */

import java.io.*;

/**
 * 定义一个工具类FileUtil类
 * 1.将一个文件拷贝到指定的文件中(2个参数) aa.txt    bb.txt
 * 2.将一个目录拷贝到指定的目录中(2个参数)aa   bb
 */
public class FileUtil {

    /**
     * 将一个文件拷贝到指定的文件中
     *
     * @param src    源文件
     * @param target 目标文件
     */
    public static void copyFile(File src, File target) {
        try (
                InputStream in = new FileInputStream(src);
                OutputStream out = new FileOutputStream(target);
        ) {
            byte[] b = new byte[1024];
            int i = -1;
            while ((i = in.read(b)) != -1) {
                out.write(b, 0, i);
            }

            out.flush();
            System.out.println("文件复制成功！！");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    /**
     * @param src    源文件字符串路径
     * @param target 目标文件的字符串路径
     */
    public static void copyFile(String src, String target) {
        copyFile(new File(src), new File(target));
    }

    /**
     * 将一个目录拷贝到指定的目录中
     *
     * @param src    列出来的目录
     * @param target 指定目录
     */
    public static void copyDirectory(String src, String target) {//aa中c.txt     bb
        File srcFile = new File(src);
        File[] files = srcFile.listFiles();

        //创建目标目录
        File fileTarget = new File(target);
        fileTarget.mkdirs();
        for (File f : files) {
            if (f.isFile()) {//如果是一个文件,则拷贝到指定目录中

                //d:\Users\User\Desktop\bbbb+分隔符+文件名称
                System.out.println(target + File.separator + f.getName());
                copyFile(f, new File(target + File.separator + f.getName()));
            }
        }

    }

    /**
     * 将一个目录中的文件与子目录递归拷贝到一个指定的目录中去
     *
     * @param src
     * @param target
     */
    public static void multiCopy(String src, String target) {//d:\Users\User\Desktop\a    d:\Users\User\Desktop\q
        File srcFile = new File(src);  //第二次d:\Users\User\Desktop\a\bb
        //获取该目录中的所有的内容
        File[] files = srcFile.listFiles();//bb文件夹 和cc.txt   第二次 dd.txt

        //创建目标目录
        File targetFile = new File(target);//d:\Users\User\Desktop\q\bb
        targetFile.mkdirs();//创建对应的q文件夹   创建对应的bb文件夹

        //循环遍历所有的内容(内容中包含子目录和子文件)
        for (File f : files) {//第一次：bb文件夹 和cc.txt   第二次:dd.txt
            if (f.isDirectory()) {//是目录
                //递归操作，将当前的子目录中的资源拷贝到目标目录中的子目录中，子目录与当前目录名一致
                multiCopy(f.getAbsolutePath(), target + File.separator + f.getName());//(d:\Users\User\Desktop\a\bb,d:\Users\User\Desktop\q\bb)

            } else {//是子文件
                copyFile(f, new File(target, f.getName()));//copyFile(cc文件实例,new File("d:\Users\User\Desktop\q","cc.txt"))   copyFile(dd文件的绝对路径的文件实例,new File(d:\Users\User\Desktop\q\b,"dd.txt"))
            }
        }


    }


    /**
     * 拆分文件，将一个文件按照大小拆分成多个文件
     *
     * @param path   指定文件的路径
     * @param length 指定每次读取的字节数
     */
    public static void seperateFile(String path, int length) {
        try {
            FileInputStream in = new FileInputStream(path);

            //设置每次读取的字节数
            byte[] b = new byte[length];

            int index = 1;
            int i = -1;
            while ((i = in.read(b)) != -1) {
                FileOutputStream os = new FileOutputStream(path + "_" + index++);
                os.write(b, 0, i);
                os.close();

            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static void copyStream(FileInputStream in, FileOutputStream out) throws IOException {
        byte[] b = new byte[1024];
        int i = -1;
        while ((i = in.read(b)) != -1) {
            out.write(b, 0, i);
        }
    }


    /**
     * 将多个文件合并成一个文件
     *
     * @param firstFile 第一个散落的文件名称
     */
    public static void mergeFile(File firstFile) {


        try {
            String path = firstFile.getAbsolutePath();//获取其绝对路径
            // path=path.replaceAll("_[0-9]+","");
            path = path.substring(0, path.lastIndexOf("_"));//将传入的文件路径中数字给清除掉
            FileOutputStream out = new FileOutputStream(path);//指定一个输出流用于接收输出的数据

            int index = 1;
            File file = null;
            //判断文件是否存在，如果存在，希望合并操作
            while ((file = new File(path + "_" + index++)).exists()) {
                FileInputStream in = new FileInputStream(file);
                copyStream(in, out);
                in.close();//关闭当前的输入流
                System.out.println(file.getAbsolutePath() + "合并成功");
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

    }

    /**
     * 文件加密
     * 按字节读取，每个字节通过异或操作实现加密
     * 加密后的添加.sec后缀
     * ^异或,如果两位相同,则结果为0, 否则结果为1
     * @param file
     * @param password
     */
    public static void encode(File file, int password) {
        try (

                FileInputStream in = new FileInputStream(file);
                FileOutputStream out=new FileOutputStream(file.getAbsoluteFile()+".sec");

        ) {
            int data=-1;
            while((data=in.read())!=-1){
                out.write(data^password);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 文件解密
     * 按字节读取加密后的文件，通过异或解密
     * @param file
     * @param password
     */
    public static void decode(File file, int password){


        try (

                FileInputStream in = new FileInputStream(file);
                FileOutputStream out=new FileOutputStream( file.getAbsolutePath().substring(0,file.getAbsolutePath().lastIndexOf(".")));

        ) {
            int data=-1;
            while((data=in.read())!=-1){
                out.write(data^password);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
